﻿using System;
using System.Reflection;

namespace UnitTesting.Fixturing
{
	abstract class ConstructorSelectorBase<T>
	{
		readonly Type _type;
		readonly ConstructorInfo[] _constructors;

		internal ConstructorSelectorBase()
			: this(new ConstructorsForDynamicProxy())
		{
		}

		internal ConstructorSelectorBase(IConstructors constructors)
		{
			_type = typeof (T);
			_constructors = constructors.GetFor(_type);
		}

		internal virtual ConstructorInfo Select()
		{
			EnsureIsNotEmpty();
			return EnsureIsNotNull(Select(_constructors));
		}

		void EnsureIsNotEmpty()
		{
			if (_constructors.Length == 0)
			{
				throw new NoConstructorException(_type);
			}
		}

		protected internal abstract ConstructorInfo Select(ConstructorInfo[] constructors);

		ConstructorInfo EnsureIsNotNull(ConstructorInfo constructor)
		{
			if (constructor == null)
			{
				throw new NoMatchedConstructorException(_type);
			}
			return constructor;
		}
	}
}